# 面向对象知识总结

# 面向对象编程（Object-Oriented Programming，OOP）是一种编程范式，其主要特点是把数据和对数据的操作包装在一起，形成“对象”。
# 这样的编程方式使得代码的组织和维护更加简洁、明了。Python 作为一门多范式编程语言，支持面向对象编程。

# 类与对象：
# 类（Class）是面向对象编程的基础，它定义了一种类型的行为（方法）和状态（属性）。对象（Object）是类的实例，它具有类定义的行为和状态。创建类的实例被称为实例化。
# 创建一个类
# 注意：self关键字在 Python 类中用于指向实例对象本身。在方法中使用 self 可以访问和修改对象的属性。
class Car:
    # 初始化方法，用于设置初始状态
    def __init__(self, color, brand):
        self.color = color
        self.brand = brand

    # 定义一个方法
    def honk(self):
        print(f"The {self.color} {self.brand} car is honking.")


# 创建一个对象
my_car = Car("red", "Toyota")
my_car.honk()  # 输出：The red Toyota car is honking.


# 下面的代码定义了一个Person类，它有两个属性name和age，以及一个方法say_hello。__init__是一个特殊的方法，用于初始化对象的属性。
# 要创建一个类的实例（对象），可以使用类名后面加上括号，并传入初始化方法中定义的参数。
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def sayHello(self):
        print(f'Hello my name is {self.name},i am {self.age} years old.')


p1 = Person('Ashe', 18)
p1.sayHello()


# 封装：
# 封装是面向对象编程的一个重要特性，它可以隐藏对象的内部状态，并只暴露出必要的接口。在 Python 中，可以使用私有属性（前缀为 __ 的属性）来实现封装。
class BankAccount:
    def __init__(self):
        self.__balance = 0  # 私有属性

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
        else:
            print("Deposit amount must be positive.")

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
        else:
            print("Withdraw amount must be positive and not exceed the balance.")


# 继承：
# 继承允许创建一个新的类（子类），继承并扩展一个现有的类（父类）。子类可以使用父类的所有属性和方法，也可以添加新的属性和方法，或者重写父类的方法。
# 定义一个父类
class Vehicle:
    def __init__(self, color):
        self.color = color

    def honk(self):
        print(f"The {self.color} vehicle is honking.")


# 定义一个子类
class Car(Vehicle):
    def __init__(self, color, brand):
        super().__init__(color)  # 调用父类的初始化方法
        self.brand = brand

    # 重写父类的方法
    def honk(self):
        print(f"The {self.color} {self.brand} car is honking.")


my_car = Car("red", "Toyota")
my_car.honk()  # 输出：The red Toyota car is honking.


# ==============================================================================================================================================================
class Animal:


    def __init__(self, name):
        self.name = name


def speak(self):
    raise NotImplementedError("Subclass must implement abstract method")


class Dog(Animal):
    def speak(self):
        return "Woof!"


class Cat(Animal):
    def speak(self):
        return "Meow!"


dog = Dog("Buddy")
cat = Cat("Kitty")
print(dog.speak())  # 输出：Woof!
print(cat.speak())  # 输出：Meow!


# ==============================================================================================================================================================

# 多态：
# 多态是指不同的对象可以响应同一种方法调用，但具体的行为取决于对象的实际类型。这使得我们可以编写更加通用的代码。
def make_it_honk(vehicle):
    vehicle.honk()  # 调用的具体行为取决于 vehicle 的类型


car = Car("red", "Toyota")
make_it_honk(car)  # 输出：The red Toyota car is honking.

# 如果我们有另一个类型的 Vehicle，例如 Bicycle，只要它也有 honk 方法，就可以使用同样的函数
# 面向对象编程有许多其他的高级概念，比如抽象类、接口、方法重载、运算符重载等，但以上内容是最基本和最重要的。
# 在使用 Python 进行面向对象编程时，需要注意以下几点：
# 注意遵循类的命名规范。通常情况下，类名应该使用 CamelCase（驼峰）命名法。
# 避免直接访问或修改对象的内部状态。应该通过方法来访问和修改对象的状态，这是封装的原则。
# 当重写父类的方法时，要确保保持相同的方法签名和相似的行为。否则，可能会破坏多态。
# 虽然 Python 支持多重继承，但是多重继承会增加代码的复杂性，应该尽量避免使用。
# 要理解并利用 Python 的动态类型特性。例如，你可以创建接收任何实现了特定方法的对象的函数，而不仅仅是特定类型的对象。这是鸭子类型（Duck Typing）的概念。
